﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using IndexingHandler;
using System.Xml;

namespace QueueIndexing
{
    static class ServiceProcs
    {
        // Процедура возвращает параметры, которые не храним вне приложения
        static private string getParamStrValue(ParamTypes paramType)
        {
            if (paramType == ParamTypes.FolderForSaveData) return "\\PortalIndexing\\";
            if (paramType == ParamTypes.FileNameForSaveData) return "connection_params.xml";
            if (paramType == ParamTypes.NodeNameParams) return "params";
            if (paramType == ParamTypes.NodeNameConnectionParams) return "connection_params";
            if (paramType == ParamTypes.NodeNameParamServer) return "server";
            if (paramType == ParamTypes.NodeNameParamDatabase) return "database";
            if (paramType == ParamTypes.NodeNameParamSchema) return "schema";
            if (paramType == ParamTypes.NodeNameParamUser) return "user";
            if (paramType == ParamTypes.NodeNamePassword) return "pass";
            if (paramType == ParamTypes.NodeNameParamDomainAuth) return "domain_auth";
            if (paramType == ParamTypes.NodeNameConfigParams) return "config_params";
            if (paramType == ParamTypes.NodeNameConfigFile) return "config_file";
            if (paramType == ParamTypes.NodeNameLogFile) return "log_file";
            return "";
        }
        // Процедура записывает список параметров подключения в Xml файл
        static public void SaveParamsToXml(QueueHandler queueHandler)
        {
            string directory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + getParamStrValue(ParamTypes.FolderForSaveData);
            string fileName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + getParamStrValue(ParamTypes.FolderForSaveData) + getParamStrValue(ParamTypes.FileNameForSaveData);
            // Создадим директорию, если ее еще нет
            if (!System.IO.Directory.Exists(directory)) { System.IO.Directory.CreateDirectory(directory); }
            StreamWriter streamWriter = new StreamWriter(fileName, false, System.Text.Encoding.UTF8);
            //Запишем заголовок
            streamWriter.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            // Запишем параметры
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameParams) + ">");
            // Подключение к БД
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameConnectionParams) + ">");
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameParamServer) + ">" + queueHandler.dbHandler.ServerName + "</" + getParamStrValue(ParamTypes.NodeNameParamServer) + ">");
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameParamDatabase) + ">" + queueHandler.dbHandler.Database + "</" + getParamStrValue(ParamTypes.NodeNameParamDatabase) + ">");
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameParamSchema) + ">" + queueHandler.dbHandler.Schema + "</" + getParamStrValue(ParamTypes.NodeNameParamSchema) + ">");
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameParamUser) + ">" + queueHandler.dbHandler.UserName + "</" + getParamStrValue(ParamTypes.NodeNameParamUser) + ">");
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameParamDomainAuth) + ">" + queueHandler.dbHandler.DomainAuth + "</" + getParamStrValue(ParamTypes.NodeNameParamDomainAuth) + ">");
            using (var secureString = queueHandler.dbHandler.Pwd.ToSecureString())
            {
                streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNamePassword) + ">" + secureString.EncryptString() + "</" + getParamStrValue(ParamTypes.NodeNamePassword) + ">");
            }
            streamWriter.WriteLine("</" + getParamStrValue(ParamTypes.NodeNameConnectionParams)  + ">");
            // Конфигурация индексатора
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameConfigParams) + ">");
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameConfigFile) + ">" + queueHandler.configFile + "</" + getParamStrValue(ParamTypes.NodeNameConfigFile) + ">");
            streamWriter.WriteLine("<" + getParamStrValue(ParamTypes.NodeNameLogFile) + ">" + queueHandler.logHandler.fileName + "</" + getParamStrValue(ParamTypes.NodeNameLogFile) + ">");
            streamWriter.WriteLine("</" + getParamStrValue(ParamTypes.NodeNameConfigParams) + ">");
            
            streamWriter.WriteLine("</" + getParamStrValue(ParamTypes.NodeNameParams) + ">");
            streamWriter.Close();
        }

        // Процедура загружает параметры подключения из XML файла
        static public QueueHandler LoadParamsFromXml()
        {
            QueueHandler queueHandler = new QueueHandler { dbHandler = new DBHandler(), logHandler = new LogHandler() };
            DBHandler dbHandler = queueHandler.dbHandler;
            string fileName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + getParamStrValue(ParamTypes.FolderForSaveData) + getParamStrValue(ParamTypes.FileNameForSaveData);
            // Проверим на наличие файла
            if (!System.IO.File.Exists(fileName)) { return queueHandler; }
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(fileName);
            // Подключение к БД
            XmlNode paramNode = xDoc.DocumentElement.SelectNodes("/" + getParamStrValue(ParamTypes.NodeNameParams) + "/" + getParamStrValue(ParamTypes.NodeNameConnectionParams)).Item(0);
            if (paramNode != null)
            {
                if (paramNode.HasChildNodes)
                {
                    XmlNodeList xNodeList;
                    XmlNode xNode;
                    xNodeList = paramNode.ChildNodes;
                    for (int x = 0; x <= xNodeList.Count - 1; x++)
                    {
                        xNode = paramNode.ChildNodes[x];
                        if (xNode.Name == getParamStrValue(ParamTypes.NodeNameParamServer)) dbHandler.ServerName = xNode.InnerText;
                        if (xNode.Name == getParamStrValue(ParamTypes.NodeNameParamDatabase)) dbHandler.Database = xNode.InnerText;
                        if (xNode.Name == getParamStrValue(ParamTypes.NodeNameParamSchema)) dbHandler.Schema = xNode.InnerText;
                        if (xNode.Name == getParamStrValue(ParamTypes.NodeNameParamUser)) dbHandler.UserName = xNode.InnerText;
                        if (xNode.Name == getParamStrValue(ParamTypes.NodeNamePassword))
                        {
                            using (var secureString = xNode.InnerText.DecryptString())
                            {
                                dbHandler.Pwd = secureString.ToInsecureString();
                            }
                        }
                        if (xNode.Name == getParamStrValue(ParamTypes.NodeNameParamDomainAuth))
                        {
                            bool DomainAuth;
                            if (bool.TryParse(xNode.InnerText, out DomainAuth))
                            {
                                dbHandler.DomainAuth = DomainAuth;
                            }
                        }
                    }
                }
            }
            // Конфигурация индексатора
            paramNode = xDoc.DocumentElement.SelectNodes("/" + getParamStrValue(ParamTypes.NodeNameParams) + "/" + getParamStrValue(ParamTypes.NodeNameConfigParams)).Item(0);
            if (paramNode != null)
            {
                if (paramNode.HasChildNodes)
                {
                    XmlNodeList xNodeList;
                    XmlNode xNode;
                    xNodeList = paramNode.ChildNodes;
                    for (int x = 0; x <= xNodeList.Count - 1; x++)
                    {
                        xNode = paramNode.ChildNodes[x];
                        if (xNode.Name == getParamStrValue(ParamTypes.NodeNameConfigFile)) queueHandler.configFile = xNode.InnerText;
                        if (xNode.Name == getParamStrValue(ParamTypes.NodeNameLogFile)) queueHandler.logHandler.fileName = xNode.InnerText;
                    }
                }
            }
            return queueHandler;
        }
    }
    // Тип параметра для получения значения из функции getParamStrValue
    enum ParamTypes
    {
        FolderForSaveData,
        FileNameForSaveData,
        NodeNameParams, // Общая обертка параметров
        NodeNameConnectionParams, // Параметры подключения
        NodeNameParamServer,
        NodeNameParamDatabase,
        NodeNameParamSchema,
        NodeNameParamUser, 
        NodeNamePassword, 
        NodeNameParamDomainAuth,
        NodeNameConfigParams, // Параметры индексатора
        NodeNameConfigFile,
        NodeNameLogFile
    }
}
